//
//  PTYSwitch.h
//  ICrEAM
//
//  Created by mac on 16/10/31.
//  Copyright © 2016年 mac. All rights reserved.
//
#import "PTYSwitch.h"

@interface PTYSwitch ()

@property (nonatomic, strong) NSMutableArray *labels;
@property (nonatomic, strong) NSMutableArray *onTopLabels;
@property (nonatomic, strong) NSArray *strings;

@property (nonatomic, strong) void (^handlerBlock)(NSUInteger index);
@property (nonatomic, strong) void (^willBePressedHandlerBlock)(NSUInteger index);

@property (nonatomic, strong) UIView *backgroundView;
@property (nonatomic, strong) UIView *sliderView;
@property (nonatomic, strong) UIView *sliderBottomView;

@property (nonatomic) NSInteger selectedIndex;

@property (nonatomic, strong) CALayer *bottomBorderLayer;
@property (nonatomic, strong) CALayer *topBorderLayer;
@property (nonatomic, strong) NSMutableArray *seperateViews;

@end

@implementation PTYSwitch

- (void)dealloc {
    
}

- (instancetype)init {
    self = [super init];
    if (self) {
        
    }
    return self;
}

+ (instancetype)switchWithStringsArray:(NSArray *)strings {
    return [[PTYSwitch alloc] initWithStringsArray:strings];
}

- (instancetype)initWithStringsArray:(NSArray *)strings {
    self = [super init];
    if (self) {
        self.strings = strings;
        
        [self buildDefault];
        
        self.labels = [NSMutableArray array];
        for (int k = 0; k < self.strings.count; k++) {
            NSString *string = self.strings[k];
            UILabel *label = [[UILabel alloc] init];
            label.tag = k;
            label.text = string;
            label.font = self.labelTextFont;
            label.adjustsFontSizeToFitWidth = YES;
            label.textAlignment = NSTextAlignmentCenter;
            label.textColor = self.labelTextColorOutsideSlider;
            label.shadowColor=[UIColor clearColor];
            [self.backgroundView addSubview:label];
            [self.labels addObject:label];
            
            UITapGestureRecognizer *rec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRecognizerTap:)];
            [label addGestureRecognizer:rec];
            label.userInteractionEnabled = YES;
        }

        self.onTopLabels = [NSMutableArray array];
        for (NSString *string in self.strings) {
            UILabel *label = [[UILabel alloc] init];
            label.text = string;
            label.font = self.labelTextFont;
            label.adjustsFontSizeToFitWidth = YES;
            label.textAlignment = NSTextAlignmentCenter;
            label.textColor = self.labelTextColorInsideSlider;
            [self.sliderView addSubview:label];
            [self.onTopLabels addObject:label];
        }
        
        UIPanGestureRecognizer *sliderRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(sliderMoved:)];
        [self.sliderView addGestureRecognizer:sliderRec];
    }
    return self;
}

- (instancetype)initWithAttributedStringsArray:(NSArray *)strings {
    self = [super init];
    if (self) {
        self.strings = strings;
        
        [self buildDefault];
        
        self.labels = [NSMutableArray array];
        [self.strings enumerateObjectsUsingBlock:^(NSMutableAttributedString *str, NSUInteger idx, BOOL *stop) {
            [str addAttribute:NSForegroundColorAttributeName value:self.labelTextColorOutsideSlider range:NSMakeRange(0, str.length)];
            UILabel *label = [[UILabel alloc] init];
            label.tag = idx;
            label.attributedText = str;
            label.textAlignment = NSTextAlignmentCenter;
            
            [self.backgroundView addSubview:label];
            [self.labels addObject:label];
            
            UITapGestureRecognizer *rec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRecognizerTap:)];
            [label addGestureRecognizer:rec];
            label.userInteractionEnabled = YES;
        }];
        
        self.onTopLabels = [NSMutableArray array];
        [self.strings enumerateObjectsUsingBlock:^(NSMutableAttributedString *str, NSUInteger idx, BOOL *stop) {
            [str addAttribute:NSForegroundColorAttributeName
                        value:self.labelTextColorInsideSlider
                        range:NSMakeRange(0, str.length)];
            
            UILabel *label          = [[UILabel alloc] init];
            label.attributedText    = str;
            label.textAlignment     = NSTextAlignmentCenter;
            
            [self.sliderView addSubview:label];
            [self.onTopLabels addObject:label];
        }];
        
        UIPanGestureRecognizer *sliderRec = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                                    action:@selector(sliderMoved:)];
        [self.sliderView addGestureRecognizer:sliderRec];
    }
    return self;
}

- (void)buildDefault {
    self.cornerRadius = 0.0f;
    self.sliderOffset = 1.0f;
    
    self.backgroundColor = [UIColor colorWithRed:70/255.0 green:70/255.0 blue:70/255.0 alpha:1.0];
    self.backgroundBottomColor = self.backgroundColor;
    self.backgroundTopColor = self.backgroundColor;
    self.seperateColor = self.backgroundColor;
    
    self.sliderColor = [UIColor whiteColor];
    self.labelTextColorInsideSlider = [UIColor redColor];
    self.labelTextColorOutsideSlider = [UIColor blueColor];
    
    self.backgroundView = [[UIView alloc] init];
    self.backgroundView.backgroundColor = self.backgroundColor;
    self.backgroundView.userInteractionEnabled = YES;
    [self addSubview:self.backgroundView];
    
    self.bottomBorderLayer = [CALayer layer];
    self.bottomBorderLayer.frame = CGRectMake(0, self.backgroundView.bounds.size.height-1, self.backgroundView.bounds.size.width, 0.5);
    

    
    
    self.bottomBorderLayer.backgroundColor = self.backgroundBottomColor.CGColor;
    [self.backgroundView.layer addSublayer:self.bottomBorderLayer];
    self.topBorderLayer = [CALayer layer];
    self.topBorderLayer.frame = CGRectMake(0, 0, self.backgroundView.bounds.size.width, 0.5);
    self.topBorderLayer.backgroundColor = self.backgroundTopColor.CGColor;
    [self.backgroundView.layer addSublayer:self.topBorderLayer];
    
    self.sliderView = [[UIView alloc] init];
    self.sliderView.backgroundColor = self.sliderColor;
    self.sliderView.clipsToBounds = YES;
    [self addSubview:self.sliderView];
    
    self.sliderBottomView = [[UIView alloc] init];
    self.sliderBottomView.clipsToBounds = YES;
    self.sliderBottomView.backgroundColor = self.sliderBottomColor;
    [self.sliderView addSubview:self.sliderBottomView];
    
    self.seperateViews = [NSMutableArray array];
    for (int i = 1; i < self.strings.count; i ++) {
        UIView *view = [[UIView alloc] init];
        view.backgroundColor = self.backgroundColor;
        [self.backgroundView addSubview:view];
        [self.seperateViews addObject:view];
    }
}

- (void)setPressedHandler:(void (^)(NSUInteger))handler {
    self.handlerBlock = handler;
}

- (void)setWillBePressedHandler:(void (^)(NSUInteger))handler {
    self.willBePressedHandlerBlock = handler;
}

- (void)forceSelectedIndex:(NSInteger)index animated:(BOOL)animated {
    if (index > self.strings.count) {
        return;
    }
    
    self.selectedIndex = index;
    
    if (animated) {
        [self animateChangeToIndex:index callHandler:NO];
    } else {
        [self changeToIndexWithoutAnimation:index callHandler:NO];
    }
}

- (void)selectIndex:(NSInteger)index animated:(BOOL)animated {
    if (index > self.strings.count) {
        return;
    }
    self.selectedIndex = index;
    if (animated) {
        [self animateChangeToIndex:index callHandler:NO];
    } else {
        [self changeToIndexWithoutAnimation:index callHandler:NO];
    }
}

- (void)layoutSubviews {
    self.backgroundView.layer.cornerRadius = self.cornerRadius;
    self.sliderView.layer.cornerRadius = self.cornerRadius;
    
    self.backgroundView.backgroundColor = self.backgroundColor;
    self.bottomBorderLayer.backgroundColor = self.backgroundBottomColor.CGColor;
    self.topBorderLayer.backgroundColor = self.backgroundTopColor.CGColor;
    
    self.sliderView.backgroundColor = self.sliderColor;
    
    self.backgroundView.frame = [self convertRect:self.frame fromView:self.superview];
    self.bottomBorderLayer.frame = CGRectMake(0, self.backgroundView.bounds.size.height-1, self.backgroundView.bounds.size.width, 1);
    self.topBorderLayer.frame = CGRectMake(0, 0, self.backgroundView.bounds.size.width, 1);
    
    self.backgroundView.layer.cornerRadius = self.cornerRadius;
    self.sliderView.layer.cornerRadius = self.cornerRadius;
    
    CGFloat sliderWidth = self.frame.size.width / [self.strings count];
    self.sliderView.frame = CGRectMake(sliderWidth * self.selectedIndex + self.sliderOffset, self.backgroundView.frame.origin.y + self.sliderOffset, sliderWidth - self.sliderOffset * 2, self.frame.size.height - self.sliderOffset * 2);
    self.sliderBottomView.backgroundColor = self.sliderBottomColor;
    self.sliderBottomView.frame = CGRectMake(0, self.sliderView.height - 2, self.sliderView.width, 2);
    self.sliderBottomView.opaque = YES;
    self.sliderBottomView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
    
    for (int i = 0; i < [self.labels count]; i++) {
        UILabel *label = self.labels[i];
        label.frame = CGRectMake(i * sliderWidth, 0, sliderWidth, self.frame.size.height);
        if (self.labelTextFont) {
            label.font = self.labelTextFont;
        }
        label.textColor = self.labelTextColorOutsideSlider;
    }
    
    NSUInteger offsetHeight = 6;
    for (int i = 0; i < self.seperateViews.count; i++) {
        UIView *view = self.seperateViews[i];
        view.frame = CGRectMake((i+1) * sliderWidth, offsetHeight, 1, self.frame.size.height - 2 * offsetHeight);
        view.backgroundColor = self.seperateColor;
    }
    
    for (int j = 0; j < [self.onTopLabels count]; j++) {
        UILabel *label = self.onTopLabels[j];
        label.frame = CGRectMake([self.sliderView convertPoint:CGPointMake(j * sliderWidth, 0) fromView:self.backgroundView].x, - self.sliderOffset, sliderWidth, self.frame.size.height);
        if (self.labelTextFont) {
            label.font = self.labelTextFont;
        }
        label.textColor = self.labelTextColorInsideSlider;
    }
}

- (void)animateChangeToIndex:(NSInteger)selectedIndex callHandler:(BOOL)callHandler {
    if (self.willBePressedHandlerBlock) {
        self.willBePressedHandlerBlock(selectedIndex);
    }
    [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        CGFloat sliderWidth = self.frame.size.width / [self.strings count];
        CGRect oldFrame = self.sliderView.frame;
        CGRect newFrame = CGRectMake(sliderWidth * self.selectedIndex + self.sliderOffset, self.backgroundView.frame.origin.y + self.sliderOffset, sliderWidth - 2 * self.sliderOffset, self.frame.size.height - 2 * self.sliderOffset);
        CGRect offRect = CGRectMake(newFrame.origin.x - oldFrame.origin.x, newFrame.origin.y - oldFrame.origin.y, 0, 0);
        self.sliderView.frame = newFrame;
        
        for (UILabel *label in self.onTopLabels) {
            label.frame = CGRectMake(label.frame.origin.x - offRect.origin.x, label.frame.origin.y - offRect.origin.y, label.frame.size.width, label.frame.size.height);
        }
        
    } completion:^(BOOL finished) {
        if (self.handlerBlock && callHandler) {
            self.handlerBlock(selectedIndex);
        }
    }];
}

- (void)changeToIndexWithoutAnimation:(NSUInteger)selectedIndex callHandler:(BOOL)callHandler {
    if (self.willBePressedHandlerBlock) {
        self.willBePressedHandlerBlock(selectedIndex);
    }
    CGFloat sliderWidth = self.frame.size.width / [self.strings count];
    
    CGRect oldFrame = self.sliderView.frame;
    CGRect newFrame = CGRectMake(sliderWidth * self.selectedIndex + self.sliderOffset, self.backgroundView.frame.origin.y + self.sliderOffset, sliderWidth - self.sliderOffset * 2, self.frame.size.height - self.sliderOffset * 2);
    
    CGRect offRect = CGRectMake(newFrame.origin.x - oldFrame.origin.x, newFrame.origin.y - oldFrame.origin.y, 0, 0);
    
    self.sliderView.frame = newFrame;
    
    for (UILabel *label in self.onTopLabels) {
        
        label.frame = CGRectMake(label.frame.origin.x - offRect.origin.x, label.frame.origin.y - offRect.origin.y, label.frame.size.width, label.frame.size.height);
    }
    
    if (self.handlerBlock && callHandler) {
        self.handlerBlock(selectedIndex);
    }
}

- (void)handleRecognizerTap:(UITapGestureRecognizer *)rec {
    self.selectedIndex = rec.view.tag;
    [self animateChangeToIndex:self.selectedIndex callHandler:YES];
}

- (void)sliderMoved:(UIPanGestureRecognizer *)rec {
    if (rec.state == UIGestureRecognizerStateChanged) {
        CGRect oldFrame = self.sliderView.frame;
        
        CGFloat minPos = 0 + self.sliderOffset;
        CGFloat maxPos = self.frame.size.width - self.sliderOffset - self.sliderView.frame.size.width;
        
        CGPoint center = rec.view.center;
        CGPoint translation = [rec translationInView:rec.view];
        
        center = CGPointMake(center.x + translation.x, center.y);
        rec.view.center = center;
        [rec setTranslation:CGPointZero inView:rec.view];
        
        if (self.sliderView.frame.origin.x < minPos) {
            self.sliderView.frame = CGRectMake(minPos, self.sliderView.frame.origin.y, self.sliderView.frame.size.width, self.sliderView.frame.size.height);
        } else if (self.sliderView.frame.origin.x > maxPos) {
            self.sliderView.frame = CGRectMake(maxPos, self.sliderView.frame.origin.y, self.sliderView.frame.size.width, self.sliderView.frame.size.height);
        }
        
        CGRect newFrame = self.sliderView.frame;
        CGRect offRect = CGRectMake(newFrame.origin.x - oldFrame.origin.x, newFrame.origin.y - oldFrame.origin.y, 0, 0);
        for (UILabel *label in self.onTopLabels) {
            label.frame = CGRectMake(label.frame.origin.x - offRect.origin.x, label.frame.origin.y - offRect.origin.y, label.frame.size.width, label.frame.size.height);
        }
    } else if (rec.state == UIGestureRecognizerStateEnded || rec.state == UIGestureRecognizerStateCancelled || rec.state == UIGestureRecognizerStateFailed) {
        NSMutableArray *distances = [[NSMutableArray alloc] init];
        
        for (int i = 0; i < [self.strings count]; i++) {
            CGFloat possibleX = i * self.sliderView.frame.size.width;
            CGFloat distance = possibleX - self.sliderView.frame.origin.x;
            [distances addObject:@(fabs(distance))];
        }
        
        NSNumber *num = [distances valueForKeyPath:@"@min.doubleValue"];
        NSInteger index = [distances indexOfObject:num];
        
        if (self.willBePressedHandlerBlock) {
            self.willBePressedHandlerBlock(index);
        }
        
        CGFloat sliderWidth = self.frame.size.width / [self.strings count];
        CGFloat desiredX = sliderWidth * index + self.sliderOffset;
        if (self.sliderView.frame.origin.x != desiredX) {
            CGRect evenOlderFrame = self.sliderView.frame;
            CGFloat distance = desiredX - self.sliderView.frame .origin.x;
            CGFloat time = fabs(distance / 300);
            [UIView animateWithDuration:time animations:^{
                self.sliderView.frame = CGRectMake(desiredX, self.sliderView.frame.origin.y, self.sliderView.frame.size.width, self.sliderView.frame.size.height);
                CGRect newFrame = self.sliderView.frame;
                CGRect offRect =CGRectMake(newFrame.origin.x - evenOlderFrame.origin.x, newFrame.origin.y - evenOlderFrame.origin.y, 0, 0);
                for (UILabel *label in self.onTopLabels) {
                    
                    label.frame = CGRectMake(label.frame.origin.x - offRect.origin.x, label.frame.origin.y - offRect.origin.y, label.frame.size.width, label.frame.size.height);
                }
            } completion:^(BOOL finished) {
                self.selectedIndex = index;
                if (self.handlerBlock) {
                    self.handlerBlock(index);
                }
            }];
        } else {
            self.selectedIndex = index;
            if (self.handlerBlock) {
                self.handlerBlock(index);
            }
        }
    }
}

@end
